package cn.schoolwow.quickdao.module.database.dql.response.service;

import cn.schoolwow.quickdao.domain.database.parent.DatabaseType;
import cn.schoolwow.quickdao.module.database.dql.parent.domain.QueryContext;
import cn.schoolwow.quickdao.module.database.dql.response.flow.update.DefaultUpdateStatementFlow;
import cn.schoolwow.quickdao.module.database.dql.response.flow.update.PostgresUpdateStatementFlow;
import cn.schoolwow.quickdao.module.database.dql.response.flow.update.SQLiteUpdateStatementFlow;
import cn.schoolwow.quickdao.module.database.dql.subCondition.domain.SubQueryOption;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.util.ArrayList;
import java.util.List;

public class UpdateFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        checkConstraint(flowContext);
        setStatement(flowContext);
        setParameters(flowContext);
        executeStatement(flowContext);
    }

    @Override
    public String name() {
        return "根据查询条件更新记录";
    }

    private void checkConstraint(FlowContext flowContext){
        QueryContext queryContext = (QueryContext) flowContext.checkData("queryContext");

        if(null==queryContext.set){
            throw new IllegalArgumentException("请调用addUpdate方法指定需要更新的列!");
        }
    }

    private void setStatement(FlowContext flowContext) {
        DatabaseType databaseType = flowContext.checkInstanceData(DatabaseType.class);

        switch (databaseType){
            case SQLite:{
                flowContext.executeFlowList(new SQLiteUpdateStatementFlow());
            }break;
            case Postgresql:{
                flowContext.executeFlowList(new PostgresUpdateStatementFlow());
            }break;
            default:{
                flowContext.executeFlowList(new DefaultUpdateStatementFlow());
            }break;
        }
    }

    private void setParameters(FlowContext flowContext) {
        QueryContext queryContext = (QueryContext) flowContext.checkData("queryContext");

        List<Object> parameters = new ArrayList<>();
        parameters.addAll(queryContext.setParameters);
        parameters.addAll(queryContext.joinParameters);
        parameters.addAll(queryContext.whereParameters);

        for(SubQueryOption subQueryOption:queryContext.queryOption.subQueryOptionList){
            parameters.addAll(subQueryOption.subQueryFragmentOption.whereParameterList);
            parameters.addAll(subQueryOption.subQueryFragmentOption.havingParameterList);
        }

        flowContext.putTemporaryData("parameters", parameters);
    }

    private void executeStatement(FlowContext flowContext) {
        flowContext.startFlow(new ExecuteUpdateConnectionFlow())
                .putTemporaryData("name", "根据查询条件更新记录")
                .execute();
    }

}
